# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.utils import timezone
# Create your models here.
from mathutils import genquestions
from django.conf import settings
from django.core.urlresolvers import reverse
import logging
from markdown_deux import markdown
from django.utils.safestring import mark_safe
from django.core.validators import MinValueValidator
import md5
from django.db.models.signals import pre_save
from django.contrib.contenttypes.models import ContentType
from comments.models import Comment


class QuestionManager(models.Manager):
    def genEquations(self, *args, **kwargs):
        type = kwargs['type']

        if type == 'file':
            for i in genquestions.genEqutionsFromFile():
                qs = Question.objects.get_or_create(expresstion=i[0].decode("utf-8"), level=i[2])
                if qs[1]:
                    q = qs[0]
                    answers = [Answer(question=q, value=str(int(i[1]) + 1)), Answer(question=q, value=str(int(i[1]) + 2)),
                           Answer(question=q, value=str(int(i[1]) - 1)), Answer(question=q, value=i[1], flag=True)]
                    Answer.objects.bulk_create(answers)
        elif type == 'random':
            for i in genquestions.genEqutions():
                qs = Question.objects.get_or_create(expresstion=i[0].decode("utf-8"), level=i[2])
                if qs[1]:
                    q=qs[0]
                    answers = [Answer(question=q, value=str(int(i[1]) + 1)), Answer(question=q, value=str(int(i[1]) + 2)),
                           Answer(question=q, value=str(int(i[1]) - 1)), Answer(question=q, value=i[1], flag=True)]
                    Answer.objects.bulk_create(answers)

    def test(self):
        print 'do anything'

    def getRightAnswer(self, *args, **kwargs):
        right_answer = super(QuestionManager, self).get(id=kwargs['id']).answer_set.filter(flag=True)
        return right_answer
    def getChooseQuesitons(self):
        qs = super(QuestionManager, self).filter(qtype='choose')
        return qs
    def getFillQuesitons(self):
        qs = super(QuestionManager, self).filter(qtype='fill')
        return qs
    def getResolveQuesitons(self):
        qs = super(QuestionManager, self).filter(qtype='resolve')
        return qs


class TestManager(models.Manager):
    def all(self):
        qs = super(TestManager, self).filter(parent=None)
        return qs
    def getChooseQuesitons(self):
        test = super(QuestionManager, self).prefetch_related('questions')
        qs=test.questions.filter(qtype='choose')
        return qs




class Topic(models.Model):
    topiccode = models.CharField(max_length=8, default='ou')
    meaning = models.CharField(max_length=8, default='一元一次方程')
    subject = models.CharField(max_length=8, default='math')
    def __unicode__(self):
        return self.meaning

    def __str__(self):
        return self.meaning

class AnswerManager(models.Manager):
    def all(self):
        qs = super(AnswerManager, self).order_by('?')
        return qs

class Question(models.Model):
    users = models.ManyToManyField(settings.AUTH_USER_MODEL, default=1)
    md5string =models.CharField(max_length=100,default='ecde697067dd080b187996a22550f6f3',unique=True)
    expresstion = models.CharField(null=True, max_length=100, verbose_name="题目")
    level = models.PositiveIntegerField(default=1, validators=[MinValueValidator(1)], verbose_name="等级")
    solution = models.CharField(max_length=20, default='0', verbose_name="答案")
    # system or custom
    type = models.CharField(max_length=10, default="system")
    # equation or ...
    category = models.CharField(max_length=20, default="base")
    # if in set of mistake
    mistakeset = models.BooleanField(default=False)
    # if archive
    archive = models.BooleanField(default=False)
    # amount of mistake
    wrongcount = models.IntegerField(default=0)
    # process of resolve
    process = models.TextField(null=True, verbose_name="解题过程")
    # create date
    create_date = models.DateTimeField(default=timezone.now)
    #math or ...
    topic = models.ForeignKey(Topic,default=1,verbose_name="题目类型")
    #question type , choose , fill
    qtype= models.CharField(max_length=10,default="choose")

    objects = QuestionManager()



    def __unicode__(self):
        return self.expresstion

    def __str__(self):
        return self.expresstion

    def get_absolute_url(self):
        return reverse("mathtest:mistakedetail", kwargs={"pk": self.id})

    def get_markdown(self):
        content = self.process
        markdown_text = markdown(content)
        return mark_safe(markdown_text)
    @property
    def get_content_type(self):
        instance = self
        content_type = ContentType.objects.get_for_model(instance.__class__)
        return content_type
    @property
    def comments(self):
        instance = self
        qs = Comment.objects.filter_by_instance(instance)
        return qs
    def save(self, *args,**kwargs):
        self.validate_unique()
        super(Question,self).save(*args, **kwargs)

class Answer(models.Model):
    question = models.ForeignKey(Question,to_field='md5string')
    value = models.CharField(max_length=10)
    flag = models.BooleanField(default=False)
    objects = AnswerManager()

    def __str__(self):
        return self.value

    def __unicode__(self):
        return self.value




class Test(models.Model):
    name = models.CharField(default=timezone.now().strftime('%Y-%m-%d %H:%M'),max_length=50)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
    questions = models.ManyToManyField(Question, blank=True, default=None)
    testdate = models.DateTimeField(default=timezone.now)
    score = models.DecimalField(max_digits=4, default=0, decimal_places=1)
    complete_time = models.CharField(default=0, max_length=10)
    parent = models.ForeignKey("self", null=True, blank=True)
    # test  belong to which topic ,default ou means one unknown equation
    topic = models.ForeignKey(Topic, default=1,verbose_name="题目类型")
    #wrongset or not
    wrongset = models.BooleanField(default=False)
    #exam or test
    type = models.CharField(default='test',max_length=10)

    objects = TestManager()

    def __str__(self):
        return self.name

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['-testdate']




    def children(self):  # replies
        return Test.objects.filter(parent=self)



    cs = set([])

    def call_gens(self, test):
        childrens = Test.objects.filter(parent=test)
        for c in childrens:
            self.cs.add(c.id)
            if c.children():
                self.call_gens(c)

    def get_all_gens(self):
        try:
            self.call_gens(self)
            return Test.objects.filter(id__in=self.cs)
        except:
            pass
        finally:
            self.cs.clear()

    @property
    def is_parent(self):
        if self.parent is not None:
            return False
        return True

    @property
    def chooses(self):
        instance = self
        qs = Choose.objects.filter_by_instance(instance)

        return qs


class Choose(models.Model):
    test = models.ForeignKey(Test)
    question = models.ForeignKey(Question, null=True)
    choose = models.ForeignKey(Answer, null=True)
    fill = models.TextField(null=True, verbose_name="解题过程")

    class Meta:
        unique_together = ('test', 'question')

    def __unicode__(self):
        return self.test.testdate.strftime('%Y-%m-%d %H:%M')

    def __str__(self):
        return self.test.testdate.strftime('%Y-%m-%d %H:%M')
def pre_save_quesiton_receiver(sender, instance, *args, **kwargs):

    instance.md5string = md5.new(instance.expresstion.encode('utf-8')).hexdigest()


pre_save.connect(pre_save_quesiton_receiver, sender=Question)